package p.ithorns.framework.core.model;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;

/**
 * @Author: liuhaitao
 * @Date: 2022/8/18 10:16
 * @Description: 帧类型
 */
@SuppressWarnings("unchecked")
public interface IType<T> extends Serializable {

    /**
     * 初始化
     *
     * @param code 编码
     * @param desc 字典文本
     */
    default void init(T code, String desc, Class<? extends IType> subType) {
        TypePool.putType(this, code, desc, subType);
    }

    /**
     * 获取编码
     *
     * @return T 具体code类型
     */
    default T getCode() {
        return TypePool.getType(this).getCode();
    }

    /**
     * 获取说明
     *
     * @return 说明内容
     */
    default String getDesc() {
        return TypePool.getType(this).getDesc();
    }


    /**
     * 转换指令编码
     *
     * @param clazz -
     * @param code  -
     * @return -
     */
    static <T, R extends IType<T>> R of(Class<? extends IType<T>> clazz, T code) {
        return Stream.of(clazz.getEnumConstants())
                .filter((IType<T> e) -> (e.getCode().equals(code)))
                .map(v -> (R) v)
                .findAny()
                .orElse(null);
    }

    class TypePool {
        private static final Map<IType, RawCode> TYPE_MAP = new ConcurrentHashMap<>();

        private static final Map<String, Class<? extends IType>> TYPE_NAME_CLASS_MAP = new ConcurrentHashMap<>();

        static <T> void putType(IType<T> type, T code, String text, Class<? extends IType> subType) {
            TYPE_NAME_CLASS_MAP.put(type.getClass().getName(), type.getClass());

            RawCode<T> rawCode = new RawCode<>(code, text, subType);
            TYPE_MAP.put(type, rawCode);
        }

        static <K extends IType<T>, T> RawCode<T> getType(K type) {
            return TYPE_MAP.get(type);
        }

    }

}